package com.cskaoyan.service;


import com.cskaoyan.bean.bo.*;
import com.cskaoyan.bean.po.*;
import com.cskaoyan.bean.vo.*;
import com.cskaoyan.mapper.*;
import com.cskaoyan.util.ConstantProperties;
import com.cskaoyan.util.Md5Util;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.lang.System;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

@Service
public class MarketServiceImpl implements MarketService {

    @Autowired
    CategoryMapper categoryMapper;
    @Autowired
    RegionMapper regionMapper;
    @Autowired
    BrandMapper brandMapper;
    @Autowired
    GoodsMapper goodsMapper;
    @Autowired
    OrderMapper orderMapper;
    @Autowired
    OrderGoodsMapper orderGoodsMapper;
    @Autowired
    UserMapper userMapper;
    @Autowired
    CommentMapper commentMapper;
    @Autowired
    CartMapper cartMapper;
    @Autowired
    AddressMapper addressMapper;
    @Autowired
    CouponMapper couponMapper;
    @Autowired
    GrouponRulesMapper grouponRulesMapper;
    @Autowired
    GoodsProductMapper goodsProductMapper;
    @Autowired
    CouponUserMapper couponUserMapper;
    @Autowired
    GrouponMapper grouponMapper;
    @Autowired
    ConstantProperties CONSTANT;

    @Override
    public CategoryData categoryList() {
        List<CategoryDataListBean> list = categoryMapper.queryCategoryByLevel(CONSTANT.getCategoryFatherLevel());
        CategoryData categoryData = new CategoryData(list.size(), CONSTANT.getPagesDefault(), list.size(), CONSTANT.getPageDefault(), null);
        for (CategoryDataListBean listBean : list) {
            List<CategoryDataChildrenBean> children = categoryMapper.queryCategoryByPid(listBean.getId());
            listBean.setChildren(children);
        }
        categoryData.setList(list);
        return categoryData;
    }

    @Override
    public Category categoryCreate(CategoryCreateBo categoryCreateBo) {
        if (CONSTANT.getCategoryFatherLevel().equals(categoryCreateBo.getLevel())) {
            int count = categoryMapper.queryCategoryByLevelAndNameAndDeleted(CONSTANT.getCategoryFatherLevel(), categoryCreateBo.getName(), false);
            if (count != 0) {
                return null;
            }
        }
        //判断是否有同名且被删除的类
        Category category = categoryMapper.selectCategoryByNameAndDeleted(categoryCreateBo.getName(), true);
        //没有查询到就新增
        if (category == null) {
            category = new Category(null, categoryCreateBo.getName(), categoryCreateBo.getKeywords(), categoryCreateBo.getDesc(), categoryCreateBo.getPid(), categoryCreateBo.getIconUrl(), categoryCreateBo.getPicUrl(), categoryCreateBo.getLevel(), null, new Date(), new Date(), false);
            if (CONSTANT.getCategoryFatherLevel().equals(category.getLevel())) {
                Byte sortOrder = categoryMapper.queryMaxSortOrder();
                sortOrder++;
                category.setSortOrder(sortOrder);
            } else {
                Category fatherCategory = categoryMapper.selectByPrimaryKey(category.getPid());
                category.setSortOrder(fatherCategory.getSortOrder());
            }
            categoryMapper.insert(category);
            return category;
        }
        //查询到改为修改
        Category result = new Category(category.getId(), categoryCreateBo.getName(), categoryCreateBo.getKeywords(), categoryCreateBo.getDesc(), categoryCreateBo.getPid(), categoryCreateBo.getIconUrl(), categoryCreateBo.getPicUrl(), categoryCreateBo.getLevel(), null, new Date(), new Date(), false);
        if (CONSTANT.getCategoryFatherLevel().equals(categoryCreateBo.getLevel())) {
            Byte sortOrder = categoryMapper.queryMaxSortOrder();
            sortOrder++;
            result.setSortOrder(sortOrder);
        } else {
            Category fatherCategory = categoryMapper.selectByPrimaryKey(categoryCreateBo.getPid());
            result.setSortOrder(fatherCategory.getSortOrder());
        }
        if (result.getDesc().equals("")) {
            result.setDesc(category.getDesc());
        }
        if (result.getKeywords().equals("")) {
            result.setKeywords(category.getKeywords());
        }
        if (result.getIconUrl().equals("")) {
            result.setIconUrl(category.getIconUrl());
        }
        if (result.getPicUrl().equals("")) {
            result.setPicUrl(category.getPicUrl());
        }
        categoryMapper.updateByPrimaryKeySelective(result);
        return category;
    }

    @Override
    public FatherCategory fatherCategoryList() {
        List<CategoryDataListBean> list = categoryMapper.queryCategoryByLevel(CONSTANT.getCategoryFatherLevel());
        FatherCategory fatherCategory = new FatherCategory(list.size(), CONSTANT.getPagesDefault(), list.size(), CONSTANT.getPageDefault(), null);
        List<FatherCategoryListBean> fatherList = new ArrayList<>();
        for (CategoryDataListBean categoryDataListBean : list) {
            fatherList.add(new FatherCategoryListBean(categoryDataListBean.getId(), categoryDataListBean.getName()));
        }
        fatherCategory.setList(fatherList);
        return fatherCategory;
    }

    @Override
    public void categoryDelete(CategoryDataListBean categoryDataListBean) {
        List<CategoryDataChildrenBean> children = categoryDataListBean.getChildren();
        if (children != null) {
            for (CategoryDataChildrenBean child : children) {
                Category category = new Category(child.getId(), child.getName(), child.getKeywords(), child.getDesc(), CONSTANT.getCategoryFatherPid(), child.getIconUrl(), child.getPicUrl(), true);
                categoryMapper.updateByPrimaryKey(category);
            }
        }
        Category category = new Category(categoryDataListBean.getId(), categoryDataListBean.getName(), categoryDataListBean.getKeywords(), categoryDataListBean.getDesc(), CONSTANT.getCategoryFatherPid(), categoryDataListBean.getIconUrl(), categoryDataListBean.getPicUrl(), true);
        categoryMapper.updateByPrimaryKey(category);
    }

    @Override
    public int categoryUpdate(CategoryUpdateBo categoryUpdateBo) {
        Category category = categoryMapper.selectByPrimaryKey(categoryUpdateBo.getId());
        //有子类不可以变为二级类目
        if (CONSTANT.getCategoryFatherLevel().equals(category.getLevel()) && categoryUpdateBo.getChildren().size() != 0 && CONSTANT.getCategorySonLevel().equals(categoryUpdateBo.getLevel())) {
            return CONSTANT.getFailCode1();
        }
        //不可以做自己的子类
        if (CONSTANT.getCategoryFatherLevel().equals(category.getLevel()) && CONSTANT.getCategorySonLevel().equals(categoryUpdateBo.getLevel()) && category.getId().equals(categoryUpdateBo.getPid())) {
            return CONSTANT.getFailCode2();
        }
        //一级类目不能同名
        int count = categoryMapper.queryCategoryByIdAndName(category.getId(), categoryUpdateBo.getName());
        if (count != 0) {
            return CONSTANT.getFailCode3();
        }
        Category result = new Category(category.getId(), categoryUpdateBo.getName(), categoryUpdateBo.getKeywords(), categoryUpdateBo.getDesc(), categoryUpdateBo.getPid(), categoryUpdateBo.getIconUrl(), categoryUpdateBo.getPicUrl(), categoryUpdateBo.getLevel(), null, null, new Date(), null);
        if (CONSTANT.getCategoryFatherLevel().equals(category.getLevel()) && CONSTANT.getCategorySonLevel().equals(categoryUpdateBo.getLevel())) {
            Byte sortOrder = categoryMapper.queryCategorySortOrderById(categoryUpdateBo.getPid());
            result.setSortOrder(sortOrder);
        } else if (CONSTANT.getCategorySonLevel().equals(category.getLevel()) && CONSTANT.getCategoryFatherLevel().equals(categoryUpdateBo.getLevel())) {
            Byte sortOrder = categoryMapper.queryMaxSortOrder();
            sortOrder++;
            result.setSortOrder(sortOrder);
        }
        categoryMapper.updateByPrimaryKeySelective(result);
        return CONSTANT.getSuccessCode();
    }

    @Override
    public RegionData regionList() {
        List<RegionData.RegionDataListBean> provinceList = regionMapper.queryProvinceListByType(CONSTANT.getProvinceType());
        for (RegionData.RegionDataListBean province : provinceList) {
            List<RegionData.RegionDataListBean.RegionDataChildrenBean> cityList = regionMapper.queryCityListByPid(province.getId());
            province.setChildren(cityList);
            for (RegionData.RegionDataListBean.RegionDataChildrenBean city : cityList) {
                List<RegionData.RegionDataListBean.RegionDataChildrenBean.RegionDataChildrenListBean> districtList = regionMapper.queryDistrictListByPid(city.getId());
                city.setChildren(districtList);
            }
        }
        RegionData regionData = new RegionData(provinceList.size(), CONSTANT.getPagesDefault(), provinceList.size(), CONSTANT.getPageDefault(), provinceList);
        return regionData;
    }

    @Override
    public BrandData brandList(BaseParam param, Integer id, String name) {
        PageHelper.startPage(param.getPage(), param.getLimit());
        BrandExample brandExample = new BrandExample();
        BrandExample.Criteria criteria = brandExample.createCriteria();
        brandExample.setOrderByClause(param.getSort() + " " + param.getOrder());
        if (id != null) {
            criteria.andIdEqualTo(id);
        }
        if (name != null) {
            criteria.andNameLike("%" + name + "%");
        }
        criteria.andDeletedEqualTo(false);
        List<Brand> brands = brandMapper.selectByExample(brandExample);
        PageInfo pageInfo = new PageInfo(brands);
        long total = pageInfo.getTotal();
        int pages = pageInfo.getPages();
        return BrandData.data(((int) total), pages, param.getLimit(), param.getPage(), brands);
    }

    @Override
    public void brandDelete(Brand brand) {
        brand.setFloorPrice(BigDecimal.ZERO);
        brand.setDeleted(true);
        brandMapper.updateByPrimaryKeySelective(brand);
        goodsMapper.updateBrandId(brand.getId());
    }

    @Override
    public int brandCreate(BrandCreateBo brandCreateBo) {
        //判断是否和已存在的品牌商重名
        int count = brandMapper.queryBrandByNameAndDelete(brandCreateBo.getName(), false);
        if (count != 0) {
            return CONSTANT.getFailCode1();
        }
        Brand brand = brandMapper.selectBrandByName(brandCreateBo.getName(), true);
        //新建
        if (brand == null) {
            Byte sortOrder = brandMapper.queryMaxSortOrder();
            sortOrder++;
            brand = new Brand(null, brandCreateBo.getName(), brandCreateBo.getDesc(), brandCreateBo.getPicUrl(), sortOrder, brandCreateBo.getFloorPrice(), new Date(), new Date(), false);
            brandMapper.insert(brand);
            return CONSTANT.getSuccessCode();
        }
        //取出旧数据建立
        if (!"".equals(brandCreateBo.getDesc())) {
            brand.setDesc(brandCreateBo.getDesc());
        }
        if (brandCreateBo.getPicUrl() != null) {
            brand.setPicUrl(brandCreateBo.getPicUrl());
        }
        brand.setFloorPrice(brandCreateBo.getFloorPrice());
        brand.setDeleted(false);
        brand.setAddTime(new Date());
        brand.setUpdateTime(new Date());
        brandMapper.updateByPrimaryKey(brand);
        return CONSTANT.getSuccessCode();
    }

    @Override
    public Brand brandUpdate(Brand brand) {
        //判断是否和已存在的品牌商重名
        int count = brandMapper.queryBrandByNameAndDeleteAndId(brand.getName(), false, brand.getId());
        if (count != 0) {
            return null;
        }

        brand.setUpdateTime(new Date());
        brandMapper.updateByPrimaryKey(brand);
        return brand;
    }

    @Override
    public OrderData orderList(BaseParam param, OrderListPostBo orderListPostBo) {
        PageHelper.startPage(param.getPage(), param.getLimit());
        OrderExample orderExample = new OrderExample();
        OrderExample.Criteria criteria = orderExample.createCriteria();
        orderExample.setOrderByClause(param.getSort() + " " + param.getOrder());
        if (orderListPostBo.getUserId() != null) {
            criteria.andUserIdEqualTo(orderListPostBo.getUserId());
        }
        if (orderListPostBo.getOrderSn() != null) {
            criteria.andOrderSnEqualTo(orderListPostBo.getOrderSn());
        }
        if (orderListPostBo.getOrderStatusArray() != null) {
            ArrayList<Short> orderStatusArray = orderListPostBo.getOrderStatusArray();
            criteria.andOrderStatusIn(orderStatusArray);
        }
        if (orderListPostBo.getStart() != null) {
            criteria.andAddTimeBetween(orderListPostBo.getStart(), orderListPostBo.getEnd());
        }
        criteria.andDeletedEqualTo(false);
        List<Order> orders = orderMapper.selectByExample(orderExample);
        PageInfo pageInfo = new PageInfo(orders);
        long total = pageInfo.getTotal();
        int pages = pageInfo.getPages();
        return OrderData.data(((int) total), pages, param.getLimit(), param.getPage(), orders);
    }

    @Override
    public OrderDetailData orderDetail(Integer id) {
        OrderDetailData orderDetailData = new OrderDetailData();
        List<OrderGoods> orderGoods = orderGoodsMapper.queryOrderGoodsByOrderId(id);
        Order order = orderMapper.selectByPrimaryKey(id);
        OrderDetailData.OrderBean orderBean = new OrderDetailData.OrderBean(order.getId(), order.getUserId(), order.getOrderSn(), order.getOrderStatus(), order.getAftersaleStatus(), order.getConsignee(), order.getMobile(), order.getAddress(), order.getMessage(), order.getGoodsPrice(), order.getFreightPrice(), order.getCouponPrice(), order.getIntegralPrice(), order.getGrouponPrice(), order.getOrderPrice(), order.getActualPrice(), order.getShipSn(), order.getShipChannel(), order.getShipTime(), order.getComments(), order.getAddTime(), order.getUpdateTime(), false);
        OrderDetailData.UserBean userBean = userMapper.queryUserBeanByUserId(order.getUserId());
        orderDetailData.setOrderGoods(orderGoods);
        orderDetailData.setOrder(orderBean);
        orderDetailData.setUser(userBean);
        return orderDetailData;
    }

    @Override
    public List<ChannelData> channelList() {
        List<ChannelData> channelDataList = orderMapper.queryChannelList();
        return channelDataList;
    }

    @Override
    public void ship(ShipDataBo shipDataBo) {
        Order order = new Order();
        order.setId(shipDataBo.getOrderId());
        order.setShipChannel(shipDataBo.getShipChannel());
        order.setShipSn(shipDataBo.getShipSn());
        order.setOrderStatus(CONSTANT.getGoodsShipStatus());
        order.setShipTime(new Date());
        order.setUpdateTime(new Date());
        orderMapper.updateByPrimaryKeySelective(order);
    }

    @Override
    public void refund(RefundDataBo refundDataBo) {
        Order order = new Order();
        order.setId(refundDataBo.getOrderId());
        order.setRefundAmount(refundDataBo.getRefundMoney());
        order.setOrderStatus(CONSTANT.getGoodsRefundStatus());
        order.setUpdateTime(new Date());
        order.setRefundTime(new Date());
        orderMapper.updateByPrimaryKeySelective(order);
    }

    @Override
    public Integer reply(AdminReplyBO adminReplyBO) {
        Comment comment = commentMapper.selectByPrimaryKey(adminReplyBO.getCommentId());
        if (comment.getAdminContent() != null && !"".equals(comment.getAdminContent())) {
            return 0;
        } else {
            comment.setAdminContent(adminReplyBO.getContent());
            commentMapper.updateByPrimaryKey(comment);
            return 1;
        }
    }

    /**
     * 微信订单模块：获取订单列表
     *
     * @param baseParam
     * @return com.cskaoyan.bean.vo.WxOrderListVO
     * @author WuHuaguo
     * @since 2022/06/07 17:00
     */
    @Override
    public WxOrderListVO wxOrderList(WxBaseParam baseParam) {
        // showType:     0全部 1待付款 2待发货 3待收货 4待评价
        // order_status:       101    201    301    401
        Integer showType = baseParam.getShowType();

        // 开启分页
        PageHelper.startPage(baseParam.getPage(), baseParam.getLimit());

        OrderExample example = new OrderExample();
        example.setOrderByClause("update_time desc");
        OrderExample.Criteria criteria = example.createCriteria();
        if (showType == 1) {
            criteria.andOrderStatusEqualTo(CONSTANT.getOrderNotPay());
        } else if (showType == 2) {
            criteria.andOrderStatusEqualTo(CONSTANT.getOrderPay());
        } else if (showType == 3) {
            criteria.andOrderStatusEqualTo(CONSTANT.getOrderShip());
        } else if (showType == 4) {
            criteria.andOrderStatusEqualTo(CONSTANT.getOrderReceive());
        }
        // 已经删除的订单不展示
        criteria.andDeletedEqualTo(false);
        List<Order> orders = orderMapper.selectByExample(example);

        ArrayList<WxOrderListVO.OrderInnerVO> orderInnerVOS = new ArrayList<>();
        for (Order order : orders) {
            WxOrderListVO.OrderInnerVO orderInnerVO = new WxOrderListVO.OrderInnerVO();
            orderInnerVO.setOrderStatusText(convertOrderStatusToString(order.getOrderStatus()));
            orderInnerVO.setAftersaleStatus(order.getAftersaleStatus());
            orderInnerVO.setOrderSn(order.getOrderSn());
            orderInnerVO.setActualPrice(order.getActualPrice());
            orderInnerVO.setId(order.getId());
            orderInnerVO.setIsGoupin(false);
            orderInnerVO.setHandleOption(getHandleOptionByOrderStatus(order.getOrderStatus()));

            // 根据orderId查询Goods信息
            OrderGoodsExample example2 = new OrderGoodsExample();
            OrderGoodsExample.Criteria criteria2 = example2.createCriteria();
            criteria2.andOrderIdEqualTo(order.getId());

            List<OrderGoods> orderGoods = orderGoodsMapper.selectByExample(example2);

            ArrayList<WxOrderListVO.OrderInnerVO.GoodsInnerVO> goodsInnerVOS = new ArrayList<>();
            for (OrderGoods good : orderGoods) {
                WxOrderListVO.OrderInnerVO.GoodsInnerVO goodsInnerVO =
                        new WxOrderListVO.OrderInnerVO.GoodsInnerVO();
                goodsInnerVO.setId(good.getId());
                goodsInnerVO.setPrice(good.getPrice());
                goodsInnerVO.setNumber(good.getNumber());
                goodsInnerVO.setPicUrl(good.getPicUrl());
                goodsInnerVO.setGoodsName(good.getGoodsName());
                goodsInnerVO.setSpecifications(good.getSpecifications());
                goodsInnerVOS.add(goodsInnerVO);
            }
            orderInnerVO.setGoodsList(goodsInnerVOS);
            orderInnerVOS.add(orderInnerVO);
        }

        // 分页
        PageInfo pageInfo = new PageInfo(orders);
        long total = pageInfo.getTotal();
        int pages = pageInfo.getPages();

        // 对返回的orderListVO赋值
        WxOrderListVO orderListVO = new WxOrderListVO();
        orderListVO.setPage(baseParam.getPage());
        orderListVO.setLimit(baseParam.getLimit());
        orderListVO.setPages(pages);
        orderListVO.setTotal((int) total);
        orderListVO.setList(orderInnerVOS);

        return orderListVO;
    }

    /**
     * 微信订单模块：订单详情
     *
     * @param orderId
     * @return com.cskaoyan.bean.vo.WxOrderDetailVO
     * @author WuHuaguo
     * @since 2022/06/07 23:13
     */
    @Override
    public WxOrderDetailVO wxOrderDetail(Integer orderId) {
        Order order = orderMapper.selectByPrimaryKey(orderId);

        WxOrderDetailVO.OrderInnerVO orderInfo = new WxOrderDetailVO.OrderInnerVO();
        orderInfo.setConsignee(order.getConsignee());
        orderInfo.setAddress(order.getAddress());
        orderInfo.setAddTime(order.getAddTime());
        orderInfo.setOrderSn(order.getOrderSn());
        orderInfo.setActualPrice(order.getActualPrice());
        orderInfo.setMobile(order.getMobile());
        orderInfo.setMessage(order.getMessage());
        orderInfo.setOrderStatusText(convertOrderStatusToString(order.getOrderStatus()));
        orderInfo.setAftersaleStatus(order.getAftersaleStatus());
        orderInfo.setGoodsPrice(order.getGoodsPrice());
        orderInfo.setCouponPrice(order.getCouponPrice());
        orderInfo.setId(orderId);
        orderInfo.setFreightPrice(order.getFreightPrice());
        orderInfo.setHandleOption(getHandleOptionByOrderStatus(order.getOrderStatus()));

        OrderGoodsExample example = new OrderGoodsExample();
        OrderGoodsExample.Criteria criteria = example.createCriteria();
        criteria.andOrderIdEqualTo(orderId);
        List<OrderGoods> goodsList = orderGoodsMapper.selectByExample(example);

        ArrayList<WxOrderDetailVO.OrderGoodsInnerVO> goodsInnerVOS = new ArrayList<>();
        for (OrderGoods orderGoods : goodsList) {
            WxOrderDetailVO.OrderGoodsInnerVO goodsInnerVO = new WxOrderDetailVO.OrderGoodsInnerVO();
            goodsInnerVO.setId(orderGoods.getId());
            goodsInnerVO.setOrderId(orderId);
            goodsInnerVO.setGoodsId(orderGoods.getGoodsId());
            goodsInnerVO.setGoodsName(orderGoods.getGoodsName());
            goodsInnerVO.setDeleted(orderGoods.getDeleted());
            goodsInnerVO.setGoodsSn(orderGoods.getGoodsSn());
            goodsInnerVO.setProductId(orderGoods.getProductId());
            goodsInnerVO.setNumber(orderGoods.getNumber());
            goodsInnerVO.setPrice(orderGoods.getPrice());
            goodsInnerVO.setSpecifications(orderGoods.getSpecifications());
            goodsInnerVO.setPicUrl(orderGoods.getPicUrl());
            goodsInnerVO.setComment(orderGoods.getComment());
            goodsInnerVO.setAddTime(orderGoods.getAddTime());
            goodsInnerVO.setUpdateTime(orderGoods.getUpdateTime());
            goodsInnerVOS.add(goodsInnerVO);
        }

        WxOrderDetailVO orderDetailVO = new WxOrderDetailVO();
        orderDetailVO.setExpressInfo(null);
        orderDetailVO.setOrderInfo(orderInfo);
        orderDetailVO.setOrderGoods(goodsInnerVOS);

        return orderDetailVO;
    }

    /**
     * 微信订单模块：申请退款
     *
     * @param wxOrderIdBO
     * @return void
     * @author WuHuaguo
     * @since 2022/06/08 11:08
     */
    @Override
    public void wxOrderRefund(WxOrderIdBO wxOrderIdBO) {
        Integer orderId = wxOrderIdBO.getOrderId();

        // 改order_status为202
        // 改refund_amount为actual_price
        Order oldOrder = orderMapper.selectByPrimaryKey(orderId);

        Order order = new Order();
        order.setId(orderId);
        order.setOrderStatus(CONSTANT.getOrderRefund());
        order.setRefundAmount(oldOrder.getActualPrice());
        order.setUpdateTime(new Date());

        orderMapper.updateByPrimaryKeySelective(order);
    }

    /**
     * 微信订单模块：删除订单
     *
     * @param wxOrderIdBO
     * @return void
     * @author WuHuaguo
     * @since 2022/06/08 14:06
     */
    @Override
    public void wxOrderDelete(WxOrderIdBO wxOrderIdBO) {
        Integer orderId = wxOrderIdBO.getOrderId();

        // 修改order中的deleted和order_goods中的deleted为true
        Order order = new Order();
        order.setId(orderId);
        order.setDeleted(true);
        order.setUpdateTime(new Date());
        orderMapper.updateByPrimaryKeySelective(order);

        OrderGoods orderGoods = new OrderGoods();
        orderGoods.setDeleted(true);
        OrderGoodsExample example = new OrderGoodsExample();
        OrderGoodsExample.Criteria criteria = example.createCriteria();
        criteria.andOrderIdEqualTo(orderId);
        orderGoodsMapper.updateByExampleSelective(orderGoods, example);
    }

    /**
     * 微信订单模块：确认收货
     *
     * @param wxOrderIdBO
     * @return void
     * @author WuHuaguo
     * @since 2022/06/08 14:31
     */
    @Override
    public void wxOrderConfirm(WxOrderIdBO wxOrderIdBO) {
        Integer orderId = wxOrderIdBO.getOrderId();

        // 修改order中的order_status为401
        Order order = new Order();
        order.setId(orderId);
        order.setOrderStatus(CONSTANT.getOrderReceive());
        order.setUpdateTime(new Date());
        orderMapper.updateByPrimaryKeySelective(order);
    }

    /**
     * 微信订单模块：取消订单
     *
     * @param wxOrderIdBO
     * @return void
     * @author WuHuaguo
     * @since 2022/06/08 15:13
     */
    @Override
    public void wxOrderCancel(WxOrderIdBO wxOrderIdBO) {
        Integer orderId = wxOrderIdBO.getOrderId();

        // 修改order中的order_status为102
        Order order = new Order();
        order.setId(orderId);
        order.setOrderStatus(CONSTANT.getOrderCancel());
        order.setUpdateTime(new Date());
        orderMapper.updateByPrimaryKeySelective(order);
    }

    /**
     * 微信订单模块：去评论中的获取商品信息
     * wx/order/goods
     *
     * @param orderId
     * @param goodsId
     * @return com.cskaoyan.bean.po.OrderGoods
     * @author WuHuaguo
     * @since 2022/06/08 16:05
     */
    @Override
    public OrderGoods wxOrderGoods(Integer orderId, Integer goodsId) {
        OrderGoodsExample example = new OrderGoodsExample();
        OrderGoodsExample.Criteria criteria = example.createCriteria();
        criteria.andOrderIdEqualTo(orderId);
        criteria.andGoodsIdEqualTo(goodsId);
        List<OrderGoods> orderGoods = orderGoodsMapper.selectByExample(example);
        return orderGoods.get(0);
    }

    /**
     * 微信订单模块：评论
     *
     * @param wxOrderCommentBO
     * @return void
     * @author WuHuaguo
     * @since 2022/06/08 16:58
     */
    @Override
    public void wxOrderComment(WxOrderCommentBO wxOrderCommentBO) {
        // order中comments减1
        // comment中新增评论，获取comment的id
        // 修改order_goods中的comment为comment中的id

        Integer orderGoodsId = wxOrderCommentBO.getOrderGoodsId();
        OrderGoods orderGoods = orderGoodsMapper.selectByPrimaryKey(orderGoodsId);
        Integer orderId = orderGoods.getOrderId();
        Integer goodsId = orderGoods.getGoodsId();

        // 1. order中comments减1
        Order order = orderMapper.selectByPrimaryKey(orderId);
        Short comments = order.getComments();
        Order order2 = new Order();
        order2.setId(order.getId());
        order2.setComments((short) (comments - 1));
        orderMapper.updateByPrimaryKeySelective(order2);

        // 2. comment中新增评论，获取comment的id
        // 2.1 获取当前用户信息
        Subject subject = SecurityUtils.getSubject();
        User user = (User) subject.getPrincipals().getPrimaryPrincipal();
        Integer userId = user.getId();
        // 2.2 新增评论
        Comment comment = new Comment();
        Date date = new Date();
        comment.setValueId(goodsId);
        comment.setType(CONSTANT.getCommentTypeGoods());
        comment.setContent(wxOrderCommentBO.getContent());
        comment.setUserId(userId);
        comment.setHasPicture(wxOrderCommentBO.getHasPicture());
        comment.setPicUrls(wxOrderCommentBO.getPicUrls());
        comment.setStar(wxOrderCommentBO.getStar());
        comment.setAddTime(date);
        comment.setUpdateTime(date);
        comment.setDeleted(false);
        commentMapper.insertSelectiveReturnId(comment);

        // 3. 修改order_goods中的comment为comment中的id
        OrderGoods orderGoods2 = new OrderGoods();
        orderGoods2.setId(orderGoodsId);
        Integer commentId = comment.getId();
        orderGoods2.setComment(commentId);
        orderGoodsMapper.updateByPrimaryKeySelective(orderGoods2);
    }

    /**
     * 微信订单模块：下单
     *
     * @return com.cskaoyan.bean.vo.WxOrderSubmitVO
     * @author WuHuaguo
     * @since 2022/06/08 21:15
     */
    @Override
    public WxOrderSubmitVO wxOrderSubmit(WxOrderSubmitBO wxOrderSubmitBO) {
        // 1. 获取userId
        Subject subject = SecurityUtils.getSubject();
        User user = (User) subject.getPrincipals().getPrimaryPrincipal();
        Integer userId = user.getId();

        Integer cartId = wxOrderSubmitBO.getCartId();

        // 2. 通过userId查询cart中所有userId为当前用户id、deleted为false、checked为1的商品
        // 先校验库存，库存不足返回null
        // 判断库存充足后，取出price(BigDecimal)、number(Short)，计算总价,赋值给goods_price
        List<Cart> carts = new ArrayList<>();
        CartExample cartExample = new CartExample();
        CartExample.Criteria criteria = cartExample.createCriteria();
        criteria.andUserIdEqualTo(userId);
        criteria.andDeletedEqualTo(false);
        criteria.andCheckedEqualTo(true);
        if (cartId == 0) {
            carts = cartMapper.selectByExample(cartExample);
        } else {
            Cart cart = cartMapper.selectByPrimaryKey(cartId);
            carts.add(cart);
        }

        // 2.1 校验库存，库存不足返回null
        for (Cart cart : carts) {
            Integer goodsId = cart.getGoodsId();
            String[] specs = cart.getSpecifications();

            // 将cart中的specs数组转为字符串形式
            StringBuffer stringBuffer = new StringBuffer();
            stringBuffer.append("[");
            for (int i = 0; i < specs.length; i++) {
                stringBuffer.append("\"").append(specs[i]).append("\"");
                if (i != specs.length - 1) {
                    stringBuffer.append(",");
                }
            }
            stringBuffer.append("]");
            String specifications = stringBuffer.toString();

            GoodsProductExample productExample = new GoodsProductExample();
            GoodsProductExample.Criteria productExampleCriteria = productExample.createCriteria();
            productExampleCriteria.andGoodsIdEqualTo(goodsId);
            productExampleCriteria.andSpecificationsEqualTo(specifications);
            List<GoodsProduct> goodsProducts = goodsProductMapper.selectByExample(productExample);

            Integer cartNumber = (int) cart.getNumber();
            Integer productNumber = goodsProducts.get(0).getNumber();
            if (cartNumber > productNumber) {
                return null;
            }
        }

        // 2.2 计算下单商品的总价
        BigDecimal goodsPrice = new BigDecimal("0");
        for (Cart cart : carts) {
            BigDecimal cartPrice = cart.getPrice();
            BigDecimal number = new BigDecimal(String.valueOf(cart.getNumber()));
            BigDecimal cartSum = cartPrice.multiply(number);
            goodsPrice = goodsPrice.add(cartSum);
        }

        // 3. 通过addressId查询address中的name(收货人名字)、tel(电话)、
        // (province、city、county、address_detail查询组合成详细地址)
        // 详细地址需要查询region表
        Integer addressId = wxOrderSubmitBO.getAddressId();
        Address addressInfo = addressMapper.selectByPrimaryKey(addressId);

        Integer provinceId = Integer.parseInt(addressInfo.getProvince());
        Integer cityId = Integer.parseInt(addressInfo.getCity());
        Integer countyId = Integer.parseInt(addressInfo.getCounty());

        Region provinceRegion = regionMapper.selectByPrimaryKey(provinceId);
        Region cityRegion = regionMapper.selectByPrimaryKey(cityId);
        Region countyRegion = regionMapper.selectByPrimaryKey(countyId);

        String province = provinceRegion.getName();
        String city = cityRegion.getName();
        String county = countyRegion.getName();
        String addressDetail = addressInfo.getAddressDetail();
        // 详细地址
        String address = province + city + county + addressDetail;
        // 电话
        String mobile = addressInfo.getTel();
        // 收货人
        String consignee = addressInfo.getName();


        // 4. 通过couponId查询coupon表中的discount优惠券金额，赋值给order中的coupon_price
        Integer couponId = wxOrderSubmitBO.getCouponId();
        BigDecimal couponPrice = null;
        if (couponId == 0 || couponId == -1) {
            // 不使用优惠券，优惠金额为0
            couponPrice = new BigDecimal("0");
        } else {
            // 使用优惠券
            Coupon coupon = couponMapper.selectByPrimaryKey(couponId);
            couponPrice = coupon.getDiscount();
        }


        // 根据grouponRulesId获取discount
        Integer grouponGoodsId = wxOrderSubmitBO.getGrouponRulesId();
        BigDecimal grouponPrice = new BigDecimal("0");
        Integer grouponRulesId = 0;
        Integer grouponIdMax = 0;

        if (grouponGoodsId != 0) {
            GrouponRulesExample grouponRulesExample = new GrouponRulesExample();
            GrouponRulesExample.Criteria grouponRulesExampleCriteria = grouponRulesExample.createCriteria();
            grouponRulesExampleCriteria.andGoodsIdEqualTo(grouponGoodsId);
            List<GrouponRules> grouponRules = grouponRulesMapper.selectByExample(grouponRulesExample);
            grouponPrice = grouponRules.get(0).getDiscount();
            grouponRulesId = grouponRules.get(0).getId();

            // 插入数据到groupon表
            GrouponExample grouponExample = new GrouponExample();
            List<Groupon> grouponList = grouponMapper.selectByExample(grouponExample);
            if (grouponList != null && grouponList.size() != 0) {
                grouponIdMax = grouponList.get(0).getGrouponId();
            }
            for (Groupon groupon : grouponList) {
                Integer grouponId = groupon.getGrouponId();
                if (grouponId > grouponIdMax) {
                    grouponIdMax = grouponId;
                }
            }
            grouponIdMax++;
        }


        // 5. 订单费用order_price = goods_price + freight_price - coupon - groupon_price
        // 6. 实付费用actual_price = order_price - integral_price
        BigDecimal integralPrice = CONSTANT.getIntegralPrice();
        BigDecimal freightPrice = CONSTANT.getFreightPrice();

        BigDecimal orderPrice = goodsPrice
                .add(freightPrice)
                .subtract(couponPrice)
                .subtract(grouponPrice);
        BigDecimal actualPrice = orderPrice.subtract(integralPrice);

        // 7. 提交订单，并且将id赋值给order_sn
        Order order = new Order();
        Date date = new Date();
        Short orderStatus = CONSTANT.getOrderNotPay();
        String message = wxOrderSubmitBO.getMessage();

        order.setUserId(userId);
        order.setOrderStatus(orderStatus);
        order.setOrderSn("0");
        order.setConsignee(consignee);
        order.setMobile(mobile);
        order.setAddress(address);
        order.setMessage(message);
        order.setGoodsPrice(goodsPrice);
        order.setFreightPrice(freightPrice);
        order.setCouponPrice(couponPrice);
        order.setIntegralPrice(integralPrice);
        order.setGrouponPrice(grouponPrice);
        order.setOrderPrice(orderPrice);
        order.setActualPrice(actualPrice);
        order.setPayTime(date);
        order.setAddTime(date);
        order.setUpdateTime(date);
        order.setComments((short) carts.size());
        orderMapper.insertSelectiveReturnId(order);

        Integer orderId = order.getId();
        Order order2 = new Order();
        String orderSn = String.valueOf(orderId);
        order2.setId(orderId);
        order2.setOrderSn(orderSn);
        orderMapper.updateByPrimaryKeySelective(order2);

        // 插入数据到groupon表
        if (grouponGoodsId != 0) {
            Groupon groupon = new Groupon();
            groupon.setOrderId(orderId);
            groupon.setGrouponId(grouponIdMax);
            groupon.setRulesId(grouponRulesId);
            groupon.setUserId(userId);
            groupon.setCreatorUserId(userId);
            groupon.setStatus((short) 1);
            groupon.setAddTime(date);
            groupon.setUpdateTime(date);
            grouponMapper.insertSelective(groupon);
        }

        // 8. order_goods表中插入订单商品数据
        for (Cart cart : carts) {
            Integer productId = cart.getProductId();
            GoodsProduct product = goodsProductMapper.selectByPrimaryKey(productId);
            BigDecimal price = product.getPrice();
            Integer goodsId = cart.getGoodsId();
            String goodsName = cart.getGoodsName();
            String goodsSn = cart.getGoodsSn();
            Short number = cart.getNumber();
            String[] specifications = cart.getSpecifications();
            String picUrl = cart.getPicUrl();

            OrderGoods orderGoods = new OrderGoods();
            orderGoods.setOrderId(orderId);
            orderGoods.setGoodsId(goodsId);
            orderGoods.setGoodsName(goodsName);
            orderGoods.setGoodsSn(goodsSn);
            orderGoods.setProductId(productId);
            orderGoods.setNumber(number);
            orderGoods.setPrice(price);
            orderGoods.setSpecifications(specifications);
            orderGoods.setPicUrl(picUrl);
            orderGoods.setAddTime(date);
            orderGoods.setUpdateTime(date);
            orderGoods.setDeleted(false);
            orderGoodsMapper.insertSelective(orderGoods);
        }

        // 9. 通过userId查询cart中所有userId为当前用户id、deleted为false、checked为1的商品，
        // 并且将deleted设置为true
        Cart cart = new Cart();
        cart.setDeleted(true);
        if (cartId == 0) {
            cartMapper.updateByExampleSelective(cart, cartExample);
        } else {
            cart.setId(cartId);
            cartMapper.updateByPrimaryKeySelective(cart);
        }

        // 10. 通过userCouponId将coupon_user表中的deleted设置为true，设置used_time，赋值order_id
        Integer userCouponId = wxOrderSubmitBO.getUserCouponId();
        if (userCouponId != -1 && userCouponId != 0) {
            // 使用优惠券后才更新coupon_user表
            CouponUser couponUser = new CouponUser();
            couponUser.setId(userCouponId);
            couponUser.setUsedTime(date);
            couponUser.setDeleted(true);
            couponUser.setOrderId(orderId);
            couponUser.setStatus(CONSTANT.getCouponUserStatus1());
            couponUserMapper.updateByPrimaryKeySelective(couponUser);
        }

        // 11. 返回VO
        WxOrderSubmitVO wxOrderSubmitVO = new WxOrderSubmitVO();
        Integer grouponLinkId = wxOrderSubmitBO.getGrouponLinkId();
        wxOrderSubmitVO.setOrderId(orderId);
        wxOrderSubmitVO.setGrouponLinkId(grouponLinkId);
        return wxOrderSubmitVO;
    }

    /**
     * 微信订单模块：付款
     *
     * @param wxOrderIdBO
     * @return void
     * @author WuHuaguo
     * @since 2022/06/09 14:41
     */
    @Override
    public void wxOrderPrepay(WxOrderIdBO wxOrderIdBO) {
        // orderId用来修改订单状态order_status为已付款，
        // 设置微信付款时间pay_time
        Integer orderId = wxOrderIdBO.getOrderId();
        Order order = new Order();
        order.setId(orderId);
        order.setOrderStatus(CONSTANT.getOrderPay());
        order.setPayTime(new Date());
        orderMapper.updateByPrimaryKeySelective(order);


        // 修改库存
        OrderGoodsExample example = new OrderGoodsExample();
        OrderGoodsExample.Criteria criteria = example.createCriteria();
        criteria.andOrderIdEqualTo(orderId);
        List<OrderGoods> orderGoodsList = orderGoodsMapper.selectByExample(example);

        for (OrderGoods orderGoods : orderGoodsList) {
            Integer goodsId = orderGoods.getGoodsId();
            Short number = orderGoods.getNumber();
            Integer productId = orderGoods.getProductId();

            String[] specs = orderGoods.getSpecifications();
            StringBuffer stringBuffer = new StringBuffer();
            stringBuffer.append("[");
            for (int i = 0; i < specs.length; i++) {
                stringBuffer.append("\"").append(specs[i]).append("\"");
                if (i != specs.length - 1) {
                    stringBuffer.append(",");
                }
            }
            stringBuffer.append("]");
            String specifications = stringBuffer.toString();

            GoodsProductExample exemple2 = new GoodsProductExample();
            GoodsProductExample.Criteria criteria2 = exemple2.createCriteria();
            criteria2.andGoodsIdEqualTo(goodsId);
            criteria2.andSpecificationsEqualTo(specifications);
            List<GoodsProduct> goodsProducts = goodsProductMapper.selectByExample(exemple2);
            Integer productNumber = goodsProducts.get(0).getNumber() - number;

            GoodsProduct goodsProduct = new GoodsProduct();
            goodsProduct.setNumber(productNumber);
            goodsProduct.setId(productId);
            goodsProductMapper.updateByPrimaryKeySelective(goodsProduct);
        }
    }

    /**
     * 将订单状态转为对应的字符串
     *
     * @return java.lang.String
     * @author WuHuaguo
     * @since 2022/06/07 19:57
     */
    private String convertOrderStatusToString(Short status) {
        Short orderNotPay = CONSTANT.getOrderNotPay();
        Short orderCancel = CONSTANT.getOrderCancel();
        Short orderPay = CONSTANT.getOrderPay();
        Short orderRefund = CONSTANT.getOrderRefund();
        Short orderRefunded = CONSTANT.getOrderRefunded();
        Short orderShip = CONSTANT.getOrderShip();
        Short orderReceive = CONSTANT.getOrderReceive();

        if (status.equals(orderNotPay)) {
            return "未付款";
        } else if (status.equals(orderCancel)) {
            return "已取消";
        } else if (status.equals(orderPay)) {
            return "已付款";
        } else if (status.equals(orderRefund)) {
            return "订单取消，退款中";
        } else if (status.equals(orderRefunded)) {
            return "已退款";
        } else if (status.equals(orderShip)) {
            return "已发货";
        } else if (status.equals(orderReceive)) {
            return "已收货";
        }
        return null;
    }

    /**
     * 通过订单状态码获取helpOption对象
     *
     * @return com.cskaoyan.bean.vo.WxOrderListVO.OrderInnerVO.HandleOptionInnerVO
     * @author WuHuaguo
     * @since 2022/06/07 21:52
     */
    private WxOrderHandleOptionInnerVO getHandleOptionByOrderStatus(Short status) {
        WxOrderHandleOptionInnerVO optionInnerVO = new WxOrderHandleOptionInnerVO();

        Short orderNotPay = CONSTANT.getOrderNotPay();
        Short orderCancel = CONSTANT.getOrderCancel();
        Short orderPay = CONSTANT.getOrderPay();
        Short orderRefund = CONSTANT.getOrderRefund();
        Short orderRefunded = CONSTANT.getOrderRefunded();
        Short orderShip = CONSTANT.getOrderShip();
        Short orderReceive = CONSTANT.getOrderReceive();

        if (status.equals(orderNotPay)) {
            // 未付款
            optionInnerVO.setCancel(true);
            optionInnerVO.setPay(true);
        } else if (status.equals(orderCancel)) {
            // 订单取消
            optionInnerVO.setDelete(true);
        } else if (status.equals(orderRefund)) {
            // 订单取消，退款中
            return optionInnerVO;
        } else if (status.equals(orderRefunded)) {
            // 已退款
            optionInnerVO.setDelete(true);
        } else if (status.equals(orderPay)) {
            // 已付款
            optionInnerVO.setRefund(true);
        } else if (status.equals(orderShip)) {
            // 已发货
            optionInnerVO.setConfirm(true);
        } else if (status.equals(orderReceive)) {
            // 已收货
            optionInnerVO.setAftersale(true);
            optionInnerVO.setComment(true);
            optionInnerVO.setDelete(true);
            optionInnerVO.setRebuy(true);
        }

        return optionInnerVO;
    }

}